package com.example.idempotentdesign.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.example.idempotentdesign.entity.Idempotent;
import com.example.idempotentdesign.service.IdempotentService;
import com.example.idempotentdesign.service.impl.mapper.IdempotentMapper;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * @author liwuji
 * @date 2024/4/10
 * @desc
 **/
@Service
public class IdempotentServiceImpl implements IdempotentService {

    @Resource
    private IdempotentMapper idempotentMapper;
    @Resource
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public boolean basicDB(String id) {
        Idempotent idempotent = new Idempotent();
        idempotent.setId(Long.valueOf(id));
        try {
            idempotentMapper.insert(idempotent);

        } catch (Exception e) {
            // 已做过该业务
            return true;
        }
        // 业务执行
        return true;
    }

    @Override
    public boolean basicDB1(String id) {
        Idempotent idempotent = idempotentMapper.selectById(id);
        if (idempotent == null) {
            throw new RuntimeException("数据不存在");
        }
        LambdaUpdateWrapper<Idempotent> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(Idempotent::getVersion, idempotent.getVersion() + 1)
                .eq(Idempotent::getVersion, idempotent.getVersion());
        int update = idempotentMapper.update(null, updateWrapper);
        if (update != 1) {
            // 已做过该业务
            return true;
        }
        // 业务代码
        return false;
    }

    /**
     * 这个幂等可能导致redis被撑爆
     * @param id
     * @return
     */
    @Override
    public boolean basicRedis(String id) {
        Boolean b = redisTemplate.opsForValue().setIfAbsent("Idempotent" + ":" + id, id);
        if (!b) {
            // 已做过该业务
            return true;
        }
        try {
            // 业务处理
        }catch (Throwable e){
            // 异常时丢弃
            redisTemplate.opsForValue().getAndDelete("Idempotent" + ":" + id);
        }
        // 
        return false;
    }
}
